Developer Documentation
PATH  Mac OS X Documentation > Cocoa > Application Design for Scripting, Documents, and Undo


Previous | Chapter contents | Next | Book PDF

Scripting and Key-Value Coding

Scripting in Mac OS X relies heavily on key-value coding (KVC) to provide automatic support for executing AppleScript commands. Key-value coding is a very simple concept. Each model object defines a set of keys that it supports. A key represents a specific piece of data that the model object has. Some examples of keys familiar to those who have used AppleScript are "words," "font," "documents," and "color." The key-value coding API provides a generic and automatic way to query an object for the values of its keys and to set new values for those keys. The primitive methods for KVC are valueForKey: and takeValue:forKey: . NSObject has generic implementations of these methods that first look to use standard accessor set and get methods based on the key (such as color and setColor: for the key named "color"). If the class of the object does not implement accessor methods, KVC directly sets or gets the value of the instance variable ("color"). KVC defines many other extended methods that are implemented in terms of the two primitives as well, but these aren't discussed here since they have little bearing on how you should implement scripting support.

You should define the set of keys for your model objects and implement the accessor methods. As you design the objects of your application, think about what the keys of these objects should be and write them down somewhere as part of your design. Then when you define the scripting suites for your application, you specify the keys that each scriptable class supports. If you do this, then a great deal of scripting support comes for free.

Keys fall into three categories which have their roots in relational databases (KVC derives from the Enterprise Objects Framework, which primarily provides access to relational databases). Keys are either attribute keys (for example, "color"), to-one relationship keys (a document's NSTextStorage object), or to-many relationship keys (an application's documents). This categorization makes sense in situations other than relational databases, including scripting. In AppleScript parlance, these key types map clearly to properties and elements. Think of AppleScript elements as relationship keys (where no distinction is made between to-one and to-many relationships) and think of AppleScript properties as attribute keys.

So why is key-value coding so important for scripting? In AppleScript, "object hierarchies" define the structure of the model objects in an application. For instance, a drawing application has documents and those documents have graphic objects. The graphic objects in turn have a fill color and line thickness. Most AppleScript commands specify one or more objects within your application by drilling down this object hierarchy from parent container to child element. For instance, some graphics might be identified by the statement "graphics 5 thru 7 of the document `MyDocument' of application `MyDraw'". There has to be some way of finding these graphics so they can be acted upon. KVC makes this search entirely automatic. An application has the key "documents," which is a to-many relationship (because the application can open multiple documents). Each document has a "name" key that identifies the file it represents. To find the document named MyDocument the framework can ask for all the documents of the application and check each one's name until it finds the one named MyDocument. Because KVC defines a uniform way of asking for the value of a key ( valueForKey: ), all this work can be done automatically with no extra effort from the developer. Similarly, once the KVC-driven scripting system finds the document, it obtains the "graphics" key and from it gets elements 5 thru 7.

Those familiar with AppleScript probably recognize that the work just described is, on the Mac OS side, accomplished by the Object Support Library. The Yellow Box version of the Object Support Library knows how to use KVC to evaluate object specifiers. Instead of specifically invoking the library and passing in all sorts of evaluation handlers, the Yellow Box developer simply relies on the KVC mechanism. Of course, you can be more directly involved in the evaluation if you need to do so for performance reasons or if your scripting model does not match your internal model closely enough for the automatic support to work.

The usefulness of key-value coding does not stop with object-specifier evaluation. Most of the core commands defined by AppleScript have default implementations in the Yellow Box based on KVC. For instance, the Get Data and Set Data commands require no extra code for your objects to support if the classes for these objects define their keys properly and implement the standard accessors. The same holds true of the Move, Clone, Delete, Create, Count, and Exists commands. Most script commands have been generically implemented with KVC so most model objects will not have to worry about them at all. If your model class must handle a particular command in a special way, even if the command has a default implementation, it can do so.


Application Design for Scripting, Documents, and Undo

Previous | Chapter contents | Next | Book PDF